package net.xxcxcxcx.xc_enhancedmob.render.boss_bar;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
import net.xxcxcxcx.xc_enhancedmob.render.BaseCustomRenderer;
import net.xxcxcxcx.xc_enhancedmob.render.boss_bar.column.CustomBossBarColumn;
import net.xxcxcxcx.xc_enhancedmob.render.boss_bar.column.client.ClientCustomBossBarColumn;
import net.xxcxcxcx.xc_enhancedmob.render.boss_bar.complete.client.ClientCustomBossBarComplete;
import net.xxcxcxcx.xc_enhancedmob.render.boss_bar.unit.CustomBossBar;
import net.xxcxcxcx.xc_enhancedmob.render.boss_bar.unit.client.ClientCustomBossBar;

import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * boss血条渲染类
 * <p>负责按照实体的BossBarComponent携带的信息渲染boss血条
 * <p>会从TextureElement获取对应的信息渲染在对应的位置
 */
@Environment(EnvType.CLIENT)
public class BossBarsRendererHelper extends BaseCustomRenderer {

    private static final CopyOnWriteArrayList<ClientCustomBossBarComplete> renderList = new CopyOnWriteArrayList<>();

    public BossBarsRendererHelper(MinecraftClient client) {
        super(client);
    }

    public static void addBossBar(ClientCustomBossBarComplete bossBar) {
        getRenderList().removeIf(clientCustomBossBarComplete -> clientCustomBossBarComplete.getEntity() == bossBar.getEntity());
        getRenderList().add(bossBar);
        sort();
    }

    public static void removeBossBar(int id) {
        getRenderList().removeIf(clientCustomBossBarComplete -> clientCustomBossBarComplete.getEntity() == id);
        sort();
    }

    public static void UpdataBossBar(int id, NbtCompound nbtCompound) {
        getRenderList().forEach(clientCustomBossBarComplete -> {
            if (clientCustomBossBarComplete.getEntity() == id) {
                clientCustomBossBarComplete.readDrityCustomDataFromNbt(nbtCompound);
            }
        });
        sort();
    }

    public static void sort() {
        renderList.sort((a, b) -> {
            if (!Objects.equals(a.getSortCount().getValue(), b.getSortCount().getValue())) {
                return a.getSortCount().getValue() - b.getSortCount().getValue();
            } else return a.getName().getValue().asString().compareTo(b.getName().getValue().asString());
        });
        for (ClientCustomBossBarComplete complete : renderList) {
            complete.getBossColumn().sort((a, b) -> {
                if (!Objects.equals(a.getSortCount().getValue(), b.getSortCount().getValue())) {
                    return a.getSortCount().getValue() - b.getSortCount().getValue();
                } else return a.getName().getValue().asString().compareTo(b.getName().getValue().asString());
            });
            for (CustomBossBarColumn column : complete.getBossColumn()) {
                column.getBossBars().sort((a, b) -> {
                    if (!Objects.equals(a.getSortCount().getValue(), b.getSortCount().getValue())) {
                        return a.getSortCount().getValue() - b.getSortCount().getValue();
                    } else return a.getName().getValue().asString().compareTo(b.getName().getValue().asString());
                });
            }
        }
    }

    public static void Initialize() {
        getRenderList().clear();
    }

    public static CopyOnWriteArrayList<ClientCustomBossBarComplete> getRenderList() {
        return renderList;
    }

    public void render(MatrixStack matrices, float tickDelta) {
        int height = 0;
        int nameWidth = 0;
        Text bossName = null;
        int windowWidth = client.getWindow().getScaledWidth();
        for (ClientCustomBossBarComplete bossBarComplete : getRenderList()) {
            bossName = bossBarComplete.getName().getValue();//渲染生物名称,渲染在屏幕的最中间
            if (bossName != null && bossBarComplete.getShowname().getValue()) {
                nameWidth = client.textRenderer.getWidth(bossName);
                client.textRenderer.drawWithShadow(matrices, bossName, windowWidth / 2.0f - nameWidth / 2.0f, height, 16777215);
                height += client.textRenderer.fontHeight;
            }
            float allWidth = bossBarComplete.getWidth();
            float allHeight = bossBarComplete.getHeight();
            //依次处理血条的每一column，计算要间隔的距离
            for (CustomBossBarColumn customBossBarColumn : bossBarComplete.getBossColumn()) {
                if (customBossBarColumn instanceof ClientCustomBossBarColumn clientCustomBossBarColumn) {
                    if (clientCustomBossBarColumn.getName().getValue() != null && clientCustomBossBarColumn.getShowname().getValue()) {
                        allHeight += client.textRenderer.fontHeight;
                        break;
                    }
                }
            }
            float barspace = 20;//血条两侧留空
            float screenspace = 20;//屏幕两侧留空
            float allPrecent = (windowWidth - screenspace * 2 - bossBarComplete.getBossColumn().size() * barspace * 2) / (allWidth);
            if (allPrecent > 1f) allPrecent = 1f;
            float correction = allWidth * allPrecent / bossBarComplete.getBossColumn().size() + barspace * 2;
            //依次处理每column的渲染
            int z = bossBarComplete.getBossColumn().size();
            for (int i = 0; i < z; i++) {
                if (bossBarComplete.getBossColumn().get(i) instanceof ClientCustomBossBarColumn clientCustomBossBarColumn) {
                    float x = windowWidth / 2.0f + correction * (i - (z - 1) / 2.0f);
                    bossName = clientCustomBossBarColumn.getName().getValue();//渲染血条组名称,渲染在指定的位置
                    if (bossName != null && clientCustomBossBarColumn.getShowname().getValue()) {
                        nameWidth = client.textRenderer.getWidth(bossName);
                        client.textRenderer.drawWithShadow(matrices, bossName, x - nameWidth / 2.0f, height, 16777215);
                    }
                    float barNow = allHeight - clientCustomBossBarColumn.getHeight();
                    //渲染Column里每一个血条的内容
                    for (CustomBossBar customBossBar : clientCustomBossBarColumn.getBossBars()) {
                        if (customBossBar instanceof ClientCustomBossBar clientCustomBossBar) {
                            float barx0 = x - clientCustomBossBar.getBackground().getWidth() * allPrecent / 2.0f;
                            float barx1 = barx0 + clientCustomBossBar.getBackground().getWidth() * allPrecent;
                            float bary0 = height + barNow;
                            float bary1 = bary0 + clientCustomBossBar.getHeight();
                            bossName = customBossBar.getName().getValue();//渲染对应血条名称,渲染在指定的位置
                            if (bossName != null) {
                                nameWidth = client.textRenderer.getWidth(bossName);
                                client.textRenderer.drawWithShadow(matrices, bossName, barx0 - nameWidth, bary0, 16777215);
                            }
                            //渲染血条图标
                            if(clientCustomBossBar.hasIcon())
                            {
                                drawTexture(matrices, clientCustomBossBar.getIcon(),barx0 - nameWidth - 8, barx0 - nameWidth, bary0,bary0+8 ,getZOffset(),1,1);
                            }
                            //渲染血条背景
                            drawTexture(matrices, clientCustomBossBar.getBackground(), barx0, barx1, bary0, bary1, getZOffset(), 1, 1);
                            //渲染图标
                            //渲染下层血条
                            if (clientCustomBossBar.CalculateNowLayerCount(tickDelta) >= 0) {
                                if (clientCustomBossBar.hasNextLayer(tickDelta)) {
                                    drawTexture(matrices, clientCustomBossBar.getNextLayerTexture(tickDelta),
                                            barx0 + clientCustomBossBar.getMeterOffsetX0() * allPrecent,
                                            barx1 + clientCustomBossBar.getMeterOffsetX1() * allPrecent,
                                            bary0 + clientCustomBossBar.getMeterOffsetY0(),
                                            bary1 + clientCustomBossBar.getMeterOffsetY1(),
                                            getZOffset(), 1, 1
                                    );
                                }
                                drawTexture(matrices, clientCustomBossBar.getCurrentLayerTexture(tickDelta),
                                        barx0 + clientCustomBossBar.getMeterOffsetX0() * allPrecent,
                                        barx0 + (clientCustomBossBar.getMeterOffsetX0() * allPrecent)
                                                + (clientCustomBossBar.getBackground().getWidth() - clientCustomBossBar.getMeterOffsetX0() + clientCustomBossBar.getMeterOffsetX1())
                                                * (clientCustomBossBar.CalculateLayerPercentage(tickDelta)) * allPrecent,
                                        bary0 + clientCustomBossBar.getMeterOffsetY0(),
                                        bary1 + clientCustomBossBar.getMeterOffsetY1(),
                                        getZOffset(), clientCustomBossBar.CalculateLayerPercentage(tickDelta), 1);
                                //添加血条计量条渲染
                                if (clientCustomBossBar.isNeedMeterCover()) {
                                    drawTexture(matrices, clientCustomBossBar.getMeterCover(),
                                            barx0 + clientCustomBossBar.getMeterOffsetX0() * allPrecent,
                                            barx1 + clientCustomBossBar.getMeterOffsetX1() * allPrecent,
                                            bary0 + clientCustomBossBar.getMeterOffsetY0(),
                                            bary1 + clientCustomBossBar.getMeterOffsetY1(),
                                            getZOffset(), 1, 1
                                    );
                                }
                                client.textRenderer.draw(matrices, String.format("x%d", clientCustomBossBar.CalculateNowLayerCount(tickDelta) + (clientCustomBossBar.CalculateLayerPercentage(tickDelta) > 0.99f ? 1 : 0)), barx0 + clientCustomBossBar.getBackground().getWidth() * allPrecent, bary0, 16777215);
                            } else {
                                client.textRenderer.draw(matrices, String.format("x%d", 0), barx0 + clientCustomBossBar.getBackground().getWidth() * allPrecent, bary0, 16777215);
                            }
                            barNow += clientCustomBossBar.getHeight();
                        }
                    }
                }
            }
            height += allHeight;
            //增加空行（可选）
            height += 4;
        }
    }
}
